const { execSync } = require('child_process');
const fs = require('fs');
const path = require('path');

const config = {
  protoDir: path.resolve(__dirname, '../proto'), // .proto 根目录（绝对路径）
  outputDir: path.resolve(__dirname, '../libs/common/src/protos'), // 输出目录
  pluginPath: path.resolve(__dirname, '../node_modules/.bin/protoc-gen-ts_proto.cmd'),
};

try {
  // 清空并重建输出目录
  if (fs.existsSync(config.outputDir)) {
    fs.rmSync(config.outputDir, { recursive: true, force: true });
  }
  fs.mkdirSync(config.outputDir, { recursive: true });

  // 递归查找所有 .proto 文件
  const protoFiles = [];
  const walk = (dir) => {
    const entries = fs.readdirSync(dir, { withFileTypes: true });
    for (const entry of entries) {
      const fullPath = path.join(dir, entry.name);
      if (entry.isDirectory()) {
        walk(fullPath);
      } else if (entry.isFile() && fullPath.endsWith('.proto')) {
        protoFiles.push(fullPath);
        console.log('找到 proto 文件：', fullPath);
      }
    }
  };
  console.log('开始查找 proto 文件...');
  walk(config.protoDir);

  if (protoFiles.length === 0) {
    throw new Error('未找到任何 .proto 文件，请检查 protoDir 路径是否正确');
  }

  // 构建命令参数（处理带空格的路径，用双引号包裹）
  const cmdParts = [
    'protoc',
    // 指定 proto 根目录（解决相对路径问题）
    `-I="${config.protoDir}"`, // 路径加引号，处理空格
    // 指定 ts-proto 插件路径
    `--plugin="${config.pluginPath}"`, // 插件路径加引号
    // 指定输出目录
    `--ts_proto_out="${config.outputDir}"`, // 输出目录加引号
    // ts-proto 配置参数
    '--ts_proto_opt=nestJs=true',
    '--ts_proto_opt=outputEncodeMethods=false',
    '--ts_proto_opt=outputJsonMethods=false',
    '--ts_proto_opt=outputClientImpl=false',

    // 递归找到的所有 proto 文件（每个路径加引号）
    ...protoFiles.map(file => `"${file}"`),
  ];

  // 拼接命令（Windows 下用 & 连接，避免空格问题）
  const cmd = cmdParts.join(' ');

  console.log('执行命令：', cmd);
  execSync(cmd, { stdio: 'inherit', shell: true }); // shell: true 确保命令正确解析

  console.log(`✅ 生成成功！文件已输出到：${config.outputDir}`);
} catch (error) {
  console.error('❌ 生成失败：', error.message);
  process.exit(1);
}